<template>
  <div class="chart-component">
    <div ref="chartContainer" class="chart-container" :style="chartStyle"></div>
    <div v-if="!chartData && !previewMode" class="chart-placeholder" @click="configChart">
      <i class="el-icon-s-data placeholder-icon"></i>
      <p class="placeholder-text">点击配置图表</p>
    </div>
    
    <!-- 图表配置对话框 -->
    <el-dialog
      title="图表配置"
      v-model="configDialogVisible"
      width="600px"
      v-if="!previewMode"
    >
      <el-form :model="chartConfig" label-width="100px">
        <el-form-item label="图表标题">
          <el-input v-model="chartConfig.title" placeholder="请输入图表标题" />
        </el-form-item>
        <el-form-item label="图表类型">
          <el-select v-model="chartConfig.type" @change="handleTypeChange">
            <el-option label="折线图" value="line" />
            <el-option label="柱状图" value="bar" />
            <el-option label="饼图" value="pie" />
            <el-option label="散点图" value="scatter" />
            <el-option label="面积图" value="area" />
          </el-select>
        </el-form-item>
        <el-form-item label="数据配置">
          <el-input
            v-model="chartConfig.dataSource"
            type="textarea"
            :rows="8"
            placeholder="请输入JSON格式的数据，例如：&#10;{&#10;  &quot;xAxis&quot;: [&quot;Jan&quot;, &quot;Feb&quot;, &quot;Mar&quot;],&#10;  &quot;series&quot;: [&#10;    {&quot;name&quot;: &quot;销售额&quot;, &quot;data&quot;: [120, 200, 150]}&#10;  ]&#10;}"
          />
        </el-form-item>
        <el-form-item label="图表颜色">
          <div class="color-list">
            <el-color-picker 
              v-for="(color, index) in chartConfig.colors"
              :key="index"
              v-model="chartConfig.colors[index]"
              size="small"
            />
            <el-button size="small" @click="addColor">+</el-button>
          </div>
        </el-form-item>
      </el-form>
      
      <template #footer>
        <div class="dialog-footer">
          <el-button @click="configDialogVisible = false">取消</el-button>
          <el-button type="primary" @click="saveConfig">确定</el-button>
        </div>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, watch, onMounted, onUnmounted, nextTick } from 'vue'
import { Message } from 'element-ui'
import * as echarts from 'echarts'
import type { ComponentConfig } from '../../interface'

// Props
interface Props {
  componentData: ComponentConfig
  previewMode?: boolean
}

const props = withDefaults(defineProps<Props>(), {
  previewMode: false
})

// Emits
const emit = defineEmits<{
  update: [property: string, value: any]
}>()

// 响应式数据
const chartContainer = ref<HTMLElement>()
const configDialogVisible = ref(false)
const chartInstance = ref<echarts.ECharts>()

const chartConfig = ref({
  title: '',
  type: 'line',
  dataSource: '',
  colors: ['#409EFF', '#67C23A', '#E6A23C', '#F56C6C', '#909399']
})

// 计算属性
const chartData = computed(() => {
  try {
    return props.componentData.props?.dataSource ? 
      JSON.parse(props.componentData.props.dataSource) : null
  } catch (error) {
    console.warn('图表数据解析失败:', error)
    return null
  }
})

const chartStyle = computed(() => {
  const style = props.componentData.style || {}
  return {
    width: '100%',
    height: '100%',
    backgroundColor: style.backgroundColor || 'transparent',
    ...style
  }
})

// 配置图表
const configChart = () => {
  if (props.previewMode) return
  
  // 初始化配置
  chartConfig.value = {
    title: props.componentData.props?.title || '',
    type: props.componentData.type?.split('-')[0] || 'line',
    dataSource: props.componentData.props?.dataSource || '',
    colors: props.componentData.props?.colors || ['#409EFF', '#67C23A', '#E6A23C', '#F56C6C', '#909399']
  }
  
  configDialogVisible.value = true
}

// 保存配置
const saveConfig = () => {
  try {
    if (chartConfig.value.dataSource) {
      JSON.parse(chartConfig.value.dataSource) // 验证JSON格式
    }
    
    emit('update', 'props.title', chartConfig.value.title)
    emit('update', 'props.dataSource', chartConfig.value.dataSource)
    emit('update', 'props.colors', chartConfig.value.colors)
    
    configDialogVisible.value = false
    Message.success('图表配置保存成功')
  } catch (error) {
    Message.error('数据格式错误，请检查JSON格式')
  }
}

// 添加颜色
const addColor = () => {
  chartConfig.value.colors.push('#409EFF')
}

// 处理类型变化
const handleTypeChange = () => {
  // 根据图表类型提供示例数据
  const examples: Record<string, string> = {
    line: JSON.stringify({
      xAxis: ["Jan", "Feb", "Mar", "Apr", "May"],
      series: [
        { name: "销售额", data: [120, 200, 150, 80, 70] }
      ]
    }, null, 2),
    bar: JSON.stringify({
      xAxis: ["产品A", "产品B", "产品C", "产品D"],
      series: [
        { name: "销量", data: [120, 200, 150, 80] }
      ]
    }, null, 2),
    pie: JSON.stringify({
      series: [
        {
          name: "数据分布",
          data: [
            { name: "类别A", value: 335 },
            { name: "类别B", value: 310 },
            { name: "类别C", value: 234 },
            { name: "类别D", value: 135 }
          ]
        }
      ]
    }, null, 2)
  }
  
  if (!chartConfig.value.dataSource && examples[chartConfig.value.type]) {
    chartConfig.value.dataSource = examples[chartConfig.value.type]
  }
}

// 初始化图表
const initChart = () => {
  if (!chartContainer.value || !chartData.value) return
  
  // 销毁已存在的实例
  if (chartInstance.value) {
    chartInstance.value.dispose()
  }
  
  chartInstance.value = echarts.init(chartContainer.value)
  
  const option = generateChartOption()
  chartInstance.value.setOption(option)
}

// 生成图表配置
const generateChartOption = () => {
  if (!chartData.value) return {}
  
  const chartType = props.componentData.type?.split('-')[0] || 'line'
  const colors = props.componentData.props?.colors || chartConfig.value.colors
  
  const baseOption = {
    title: {
      text: props.componentData.props?.title || '',
      left: 'center'
    },
    color: colors,
    tooltip: {
      trigger: chartType === 'pie' ? 'item' : 'axis'
    },
    legend: {
      top: 'bottom'
    }
  }
  
  if (chartType === 'pie') {
    return {
      ...baseOption,
      series: [{
        type: 'pie',
        radius: '60%',
        center: ['50%', '50%'],
        data: chartData.value.series?.[0]?.data || [],
        emphasis: {
          itemStyle: {
            shadowBlur: 10,
            shadowOffsetX: 0,
            shadowColor: 'rgba(0, 0, 0, 0.5)'
          }
        }
      }]
    }
  } else {
    return {
      ...baseOption,
      xAxis: {
        type: 'category',
        data: chartData.value.xAxis || []
      },
      yAxis: {
        type: 'value'
      },
      series: (chartData.value.series || []).map((item: any) => ({
        ...item,
        type: chartType === 'area' ? 'line' : chartType,
        areaStyle: chartType === 'area' ? {} : undefined,
        smooth: chartType === 'line'
      }))
    }
  }
}

// 重新调整图表大小
const resizeChart = () => {
  if (chartInstance.value) {
    chartInstance.value.resize()
  }
}

// 监听数据变化
watch(chartData, () => {
  nextTick(() => {
    initChart()
  })
}, { immediate: true })

// 监听容器大小变化
watch(() => [props.componentData.position?.width, props.componentData.position?.height], () => {
  nextTick(() => {
    resizeChart()
  })
})

// 生命周期
onMounted(() => {
  nextTick(() => {
    initChart()
  })
  
  window.addEventListener('resize', resizeChart)
})

onUnmounted(() => {
  if (chartInstance.value) {
    chartInstance.value.dispose()
  }
  window.removeEventListener('resize', resizeChart)
})
</script>

<style lang="scss" scoped>
.chart-component {
  width: 100%;
  height: 100%;
  position: relative;
}

.chart-container {
  width: 100%;
  height: 100%;
}

.chart-placeholder {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  background-color: #f5f5f5;
  border: 1px dashed #ddd;
  cursor: pointer;
  transition: all 0.3s ease;

  &:hover {
    background-color: #f0f0f0;
    border-color: #409eff;
  }

  .placeholder-icon {
    font-size: 48px;
    color: #ccc;
    margin-bottom: 8px;
  }

  .placeholder-text {
    margin: 0;
    font-size: 14px;
    color: #999;
  }
}

.color-list {
  display: flex;
  gap: 8px;
  align-items: center;
  flex-wrap: wrap;
}

.dialog-footer {
  text-align: right;
}
</style>
